package xyz.ibenben.zhongdian.common.configure;

import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import xyz.ibenben.zhongdian.common.exception.ExceptionEnum;
import xyz.ibenben.zhongdian.common.exception.MyException;

import javax.sql.DataSource;
import java.sql.SQLException;

/**
 * Mybatis配置
 *
 * @author chenjian
 * @since 2017年7月26日下午6:30:31
 */
@Configuration
@EnableTransactionManagement
public class MyBatisConfig {

    /* 数据库地址 */
    @Value("${spring.datasource.url}")
    private String dbUrl;

    /* 数据库用户名 */
    @Value("${spring.datasource.username}")
    private String username;

    /* 数据库密码 */
    @Value("${spring.datasource.password}")
    private String password;

    /* 驱动名称 */
    @Value("${spring.datasource.driver-class-name}")
    private String driverClassName;

    /* 初始大小 */
    @Value("${spring.datasource.initialSize}")
    private int initialSize;

    /* 连接最小数 */
    @Value("${spring.datasource.minIdle}")
    private int minIdle;

    /* 连接最大数 */
    @Value("${spring.datasource.maxActive}")
    private int maxActive;

    /* 最大超时时间 */
    @Value("${spring.datasource.maxWait}")
    private int maxWait;

    /* timeBetweenEvictionRunsMillis */
    @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
    private int timeBetweenEvictionRunsMillis;

    /* minEvictableIdleTimeMillis */
    @Value("${spring.datasource.minEvictableIdleTimeMillis}")
    private int minEvictableIdleTimeMillis;

    /* validationQuery */
    @Value("${spring.datasource.validationQuery}")
    private String validationQuery;

    /* testWhileIdle */
    @Value("${spring.datasource.testWhileIdle}")
    private boolean testWhileIdle;

    /* testOnBorrow */
    @Value("${spring.datasource.testOnBorrow}")
    private boolean testOnBorrow;

    /* testOnReturn */
    @Value("${spring.datasource.testOnReturn}")
    private boolean testOnReturn;

    /* poolPreparedStatements */
    @Value("${spring.datasource.poolPreparedStatements}")
    private boolean poolPreparedStatements;

    /* maxPoolPreparedStatementPerConnectionSize */
    @Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
    private int maxPoolPreparedStatementPerConnectionSize;

    /* connectionProperties */
    @Value("{spring.datasource.connectionProperties}")
    private String connectionProperties;

    /**
     * 声明其为Bean实例
     * 在同样的DataSource中，首先使用被标注的DataSource
     *
     * @return 返回值
     */
    @Bean
    @Primary
    public DataSource dataSource() {
        DruidDataSource datasource = new DruidDataSource();
        //设置基本信息
        datasource.setUrl(this.dbUrl);
        datasource.setUsername(username);
        datasource.setPassword(password);
        datasource.setDriverClassName(driverClassName);

        //配置高级信息
        datasource.setInitialSize(initialSize);
        datasource.setMinIdle(minIdle);
        datasource.setMaxActive(maxActive);
        datasource.setMaxWait(maxWait);
        datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        datasource.setValidationQuery(validationQuery);
        datasource.setTestWhileIdle(testWhileIdle);
        datasource.setTestOnBorrow(testOnBorrow);
        datasource.setTestOnReturn(testOnReturn);
        datasource.setPoolPreparedStatements(poolPreparedStatements);
        datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
        try {
            datasource.setFilters("stat");
        } catch (SQLException e) {
            //抛出统一异常捕获
            throw new MyException(ExceptionEnum.SQLEXCEPTION, e);
        }
        //连接
        datasource.setConnectionProperties(connectionProperties);
        return datasource;
    }

    /**
     * mybatis-plus SQL执行效率插件
     */
    @Bean
    public PerformanceInterceptor performanceInterceptor() {
        return new PerformanceInterceptor();
    }

    /**
     * 分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }

}
